﻿using _220105BookSys.IRepository;
using _220105BookSys.Model;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace _220105BookSys.Repository
{
    public class BookRepository : IBookRepository,IDisposable
    {
        private readonly BookSysDbContext _bookSysDbContext;

        public BookRepository(BookSysDbContext bookSysDbContext)
        {
            this._bookSysDbContext = bookSysDbContext;
        }

        public async Task<bool> CreateAsync(Book book)
        {
           await this._bookSysDbContext.Books.AddAsync(book);
            return await SaveChangesAsync();
        }

        public async void Dispose()
        {
            //await this._bookSysDbContext.SaveChangesAsync();
        }

        //public async Task FakeDeleteAsync(Guid id)
        //{
        //    var book =await GetBookAsync(id);
        //    if (book==null)
        //    {
        //        throw new NullReferenceException("未找到指定对象");
        //    }
           
        //}

        public async Task<Book> GetBookAsync(Guid id)
        {
           return await this._bookSysDbContext.Books.Include(b=>b.BookType).Where(b => b.Id == id).FirstOrDefaultAsync();
        }

        public async Task<IEnumerable<Book>> GetBooksAsync()
        {
            var result = this._bookSysDbContext.Books.Include(b => b.BookType).AsQueryable();
            return await result.ToListAsync();
        }

        public async Task<IEnumerable<Book>> GetBooksAsync(bool asc)
        {
            var result = this._bookSysDbContext.Books.Include(b => b.BookType).AsQueryable();
            if (asc)
            {
                result.OrderBy(b => b.Id);
            }
            return await result.ToListAsync();
        }

        public async Task<IEnumerable<Book>> GetBooksAsync(int pageIndex, int pageSize = 10)
        {
            var result = this._bookSysDbContext.Books.Include(b => b.BookType).AsQueryable();
            result= result.Skip((pageIndex - 1) * pageSize).Take(pageSize);
            return await result.ToListAsync();
        }

        public async Task<IEnumerable<Book>> GetBooksAsync(Expression<Func<Book, bool>> expression)
        {
            var result = this._bookSysDbContext.Books.Include(b => b.BookType).AsQueryable();
            result = result.Where(expression);
            return await result.ToListAsync();
        }

        public async Task<IEnumerable<Book>> GetBooksAsync(Expression<Func<Book, bool>> expression, bool asc)
        {
            var result = this._bookSysDbContext.Books.Include(b => b.BookType).AsQueryable();
            if (asc)
            {
                result = result.Where(expression).OrderBy(b => b.Id);
            }
            else
            {
                result = result.Where(expression).OrderByDescending(b => b.Id);
            }
            return await result.ToListAsync();
            
        }

        public async Task<IEnumerable<Book>> GetBooksAsync(Expression<Func<Book, bool>> expression, bool asc, int pageIndex, int pageSize = 10)
        {
            var result = this._bookSysDbContext.Books.Include(b => b.BookType).AsQueryable();
            if (asc)
            {
                result = result.Where(expression).OrderBy(b => b.Id);
            }
            else
            {
                result = result.Where(expression).OrderByDescending(b => b.Id);
            }
            result = result.Skip((pageIndex - 1) * pageSize).Take(pageSize);
            return await result.ToListAsync();
        }

        public async Task<int> GetTotalAsync()
        {
            var result = this._bookSysDbContext.Books.AsQueryable();
            return await result.CountAsync();
        }

        public async Task<bool> IsExsitedAsync(Guid id)
        {
            if (await this._bookSysDbContext.Books.AnyAsync(b => b.Id == id))
            {
                return true;
            }
            return false;
        }

        public async Task<bool> RealDeleteAsync(Guid id)
        {
            if (await IsExsitedAsync(id))
            {
                var result =await GetBookAsync(id);
                this._bookSysDbContext.Books.Remove(result);
                return await SaveChangesAsync();
            }
            throw new NullReferenceException("未找到指定对象");
        }

        public async Task<bool> SaveChangesAsync()
        {
            if (await this._bookSysDbContext.SaveChangesAsync()>0)
            {
                return true;
            }
            return false;
        }

        public async Task<bool> UpdateAsync(Book book)
        {
            //this._bookSysDbContext.Entry<Book>(book).State = EntityState.Modified;老写法
            //this._bookSysDbContext.Set<Book>().Update(book);新写法
            //var result = await GetBookAsync(book.Id);
            //result.BookTypeId = book.BookTypeId;
            //result.Describe = book.Describe;
            //result.Name = book.Name;
            if (!(await IsExsitedAsync(book.Id)))
            {
                throw new NullReferenceException("未找到指定对象");
            }
            this._bookSysDbContext.Books.Update(book);
            return await SaveChangesAsync();
        }
    }
}
